<?php

	/**
	*  Глобальная ссылка на подключенную БД
	*/
	$mysql_db_link = null;


	/**
	*  Перехватчик ошибок по умолчанию
	*/
	if ( !function_exists( "show_error_sql" ) ) {
		function show_error_sql( $sql, $db ) {
			exit( "SQL Error: ".$sql );
		}
	}

	/**
	*  Подключение к БД, приоритет идет на рассширение MySQLi
	*/
	function db_connect( $db_host, $db_user, $db_pass, $db_name ) {

		if ( function_exists( "mysqli_connect" ) ) {

			define( "MYSQLI", true );

			$result = mysqli_connect( $db_host, $db_user, $db_pass, $db_name );

			if ( mysqli_connect_errno() ) {
				return false;
			}

		} else {

			define( "MYSQLI", false );

			$result = mysql_connect( $db_host, $db_user, $db_pass );

			if ( !$result ) {
				return false;
			}

			if ( !mysql_select_db( $db_name ) ) {
				return false;
			}
		}

		exec_sql(
			array(
				"set session character_set_client=".DB_CHARSET.";",
				"set session character_set_database=".DB_CHARSET.";",
				"set session character_set_connection=".DB_CHARSET.";",
				"set session character_set_results=".DB_CHARSET.";",
				"set session collation_connection=".DB_COLLATE.";"
			), true, $result
		);

		return $result;
	}

	/**
	*  Переводит строку мульти-запроса в массив, требуеться в том случае если нет рассширения MySQLi
	*/
	function sql_string2array( $sql ) {

		$next = -1;
		$index = 0;
		$quote_found = false;
		$skip_next = false;

		$result = array( $index => "" );

		while ( isset( $sql[ ++$next ] ) ) {

			$result[ $index ] .= $sql[ $next ];

			if ( !$quote_found && ( $sql[ $next ] == "'" || $sql[ $next ] == '"' ) ) {

				$quote_found = $sql[ $next ];

			} else if ( !$skip_next && $quote_found ) {

				if ( $sql[ $next ] == "\\" ) {

					$skip_next = true;
					continue;

				} else if ( $sql[ $next ] == $quote_found ) {

					$quote_found = false;
				}
			}

			$skip_next = false;

			if ( !$quote_found && $sql[ $next ] == ";" ) {

				$result[ $index ] = trim( $result[ $index ] );

				$result[ ++$index ] = "";
			}
		}

		$result[ $index ] = trim( $result[ $index ] );

		if ( empty( $result[ $index ] ) ) {
			unset( $result[ $index ] );
		}

		return $result;
	}

	/**
	*  Основная функция запросов
	*  @param : mixed - строка или массив (список запросов)
	*  @param : производить сброс ответа MySQL
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : ResourseID при использовании MySQLi
	*			 ResourseID/Array при использовании MySQL
	*/
	function exec_sql( $sql, $store = true, $db = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		if ( MYSQLI ) {

			$sql = is_array( $sql ) ? implode( "\r\n", $sql ) : $sql;

			mysqli_multi_query( $db, $sql ) or show_error_sql( $sql, $db );

			$result = mysqli_store_result( $db );

			if ( $store && mysqli_more_results( $db ) ) {
				while( mysqli_more_results( $db ) && mysqli_next_result( $db ) ) {
					mysqli_store_result( $db );
				}
			}
		} else {

			if ( !is_array( $sql ) ) {
				$sql = sql_string2array( $sql );
			}

			if ( $store ) {

				$query = array_shift( $sql );

				$result = mysql_query( $query, $db ) or show_error_sql( $query, $db );

				foreach( $sql as $query ) {
					mysql_query( $query, $db ) or show_error_sql( $query, $db );
				}
			} else {

				$result = array();

				foreach( $sql as $query ) {
					$result[] = mysql_query( $query, $db ) or show_error_sql( $query, $db );
				}

				$result = count( $result ) == 1 ? $result[ 0 ] : $result;
			}
		}

		return $result;
	}

	/**
	*  Функция для получения списка результатов с именованными ключами
	*  @param : mixed - строка или массив (список запросов)
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : Array
	*/
	function exec_sql2array( $sql, $db = null, $callbackStep = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		$result = array();

		$out = &$result;
		$next = 0;

		$data = exec_sql( $sql, false, $db );

		$is_callable = $callbackStep === null ? false : is_callable( $callbackStep );

		if ( MYSQLI ) {

			if ( mysqli_more_results( $db ) ) {

				$result[ $next ] = array();
				$out = &$result[ $next ];
			}

			do {
				$rows = mysqli_num_rows( $data );

				for ( $i = 0; $i < $rows; $i++ ) {

					if ( $is_callable ) {
						if ( $callbackStep( $out, $i, mysqli_fetch_assoc( $data ) ) === false ) {
							break;
						}
					} else {
						$out[] = mysqli_fetch_assoc( $data );
					}
				}

				mysqli_free_result( $data );

			} while (

				mysqli_more_results( $db ) &&

				mysqli_next_result( $db ) &&

				($data = mysqli_store_result( $db )) &&

				!($result[ ++$next ] = array()) &&

				!($out = &$result[ $next ])
			);

		} else {

			if ( is_array( $data ) ) {

				$result[ $next ] = array();
				$out = &$result[ $next ];
				$resourse = array_shift( $data );
			} else {
				$resourse = $data;
			}

			do {
				$rows = mysql_num_rows( $resourse );

				for ( $i = 0; $i < $rows; $i++ ) {

					if ( $is_callable ) {
						if ( $callbackStep( $out, $i, mysql_fetch_assoc( $resourse ) ) === false ) {
							break;
						}
					} else {
						$out[] = mysql_fetch_assoc( $resourse );
					}
				}

				mysql_free_result( $resourse );

			} while (

				is_array( $data ) &&

				count( $data ) > 0 &&

				($resourse = array_shift( $data )) &&

				!($result[ ++$next ] = array()) &&

				!($out = &$result[ $next ])
			);
		}

		return $result;
	}

	/**
	*  Функция для получения списка результатов с индексными ключами
	*  @param : mixed - строка или массив (список запросов)
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : Array
	*/
	function exec_sql2list( $sql, $db = null, $callbackStep = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		$result = array();

		$out = &$result;
		$next = 0;

		$data = exec_sql( $sql, false, $db );

		$is_callable = $callbackStep === null ? false : is_callable( $callbackStep );

		if ( MYSQLI ) {

			if ( mysqli_more_results( $db ) ) {

				$result[ $next ] = array();
				$out = &$result[ $next ];
			}

			do {
				$rows = mysqli_num_rows( $data );

				for ( $i = 0; $i < $rows; $i++ ) {
					$row = mysqli_fetch_row( $data );

					if ( $is_callable ) {
						if ( $callbackStep( $out, $i, $row[ 0 ] ) === false ) {
							break;
						}
					} else {
						$out[] = $row[ 0 ];
					}
				}

				mysqli_free_result( $data );

			} while (

				mysqli_more_results( $db ) &&

				mysqli_next_result( $db ) &&

				($data = mysqli_store_result( $db )) &&

				!($result[ ++$next ] = array()) &&

				!($out = &$result[ $next ])
			);

		} else {

			if ( is_array( $data ) ) {

				$result[ $next ] = array();
				$out = &$result[ $next ];
				$resourse = array_shift( $data );
			} else {
				$resourse = $data;
			}

			do {
				$rows = mysql_num_rows( $resourse );

				for ( $i = 0; $i < $rows; $i++ ) {
					$row = mysql_fetch_row( $resourse );

					if ( $is_callable ) {
						if ( $callbackStep( $out, $i, $row[ 0 ] ) === false ) {
							break;
						}
					} else {
						$out[] = $row[ 0 ];
					}
				}

				mysql_free_result( $resourse );

			} while (

				is_array( $data ) &&

				count( $data ) > 0 &&

				($resourse = array_shift( $data )) &&

				!($result[ ++$next ] = array()) &&

				!($out = &$result[ $next ])
			);
		}

		return $result;
	}

	/**
	*  Функция для получения имен и значений полей одной ячейки
	*  @param : mixed - строка или массив (список запросов)
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : Array
	*/
	function exec_sql2fields( $sql, $db = null, $callbackStep = null ) {

		$result = exec_sql2array( $sql, $db, $callbackStep );

		return isset( $result[ 0 ] ) ? $result[ 0 ] : array();
	}

	/**
	*  Функция для получения количества затронутых строк
	*  @param : ссылка на БД
	*  @return : Number
	*/
	function db_affected_rows( $db = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		if ( MYSQLI ) {
			return mysqli_affected_rows( $db );
		}

		return mysql_affected_rows( $db );
	}

	/**
	*  Функция для получения последнего вставленного ID - AUTO_INCREMENT
	*  @param : ссылка на БД
	*  @return : Number
	*/
	function db_insert_id( $db = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		if ( MYSQLI ) {
			return mysqli_insert_id( $db );
		}

		return mysql_insert_id( $db );
	}

	/**
	*  Функция для получения количества строк
	*  @param : string - имя таблицы
	*  @param : string - условие
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : int
	*/
	function exec_sql2count( $table, $where, $db = null, $callbackStep = null ) {

		$result = exec_sql2array( "SELECT COUNT(*) as `col` FROM `".$table."` ".$where, $db, $callbackStep );

		return isset( $result[ 0 ] ) ? $result[ 0 ]['col'] : 0;
	}

	/**
	*  Функция для экранирование ковычек и прочих запрещенных символов
	*  @param : string - строка
	*  @param : ссылка на БД в котором требуеться выполнить запрос
	*  @return : string
	*/
	function db_escape( $escapeStr, $db = null ) {

		global $mysql_db_link;

		$db = $db ? $db : $mysql_db_link;

		if ( MYSQLI ) {
			return mysqli_real_escape_string( $db, $escapeStr );
		} else {
			return mysql_real_escape_string( $escapeStr, $db );
		}
	}

	/**
	*  Подключаемся к БД по умолчанию
	*/
	$mysql_db_link = db_connect( DB_HOST_NAME, DB_USER_NAME, DB_PASSWORD, DB_NAME );
	
	/**
	*  Генерим переменные имен таблиц с учетом DB_PREFIX(см. dbconfig.php )
	*/
	$_TABLES= exec_sql2list('SHOW TABLES'); $TABLES = array();
	foreach( $_TABLES as $table ){
		$key = preg_replace('/^'.DB_PREFIX.'(\w+)$/', '${1}_table', $table);
		$TABLES[ $key ] = $table ;
	}
	extract($TABLES);
	/*
	$user_table = DB_PREFIX.'user';
	$user_data_table = DB_PREFIX.'user_data';
	$page_table = DB_PREFIX.'page';
	*/

?>